package pt.um.jspecput.lib.writer;

import static org.junit.Assert.*;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

import javax.validation.constraints.Pattern;

import org.databene.benerator.anno.InvocationCount;
import org.databene.feed4junit.Feeder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Feeder.class)
public class TestMethodWriterHelperTest {

    private static BufferedWriter writer;
    private static BufferedReader reader;
    private static File file = new File("temp");

    @Before
    public void setUp() throws Exception {
        FileHandler.createFile(file);
        writer = new BufferedWriter(new FileWriter(file));
        reader = new BufferedReader(new FileReader(file));
    }

    @After
    public void tearDown() throws Exception {
        writer.close();
        reader.close();
        file.delete();
    }

    @Test
    public void testConstructor(){
        TestMethodWriterHelper t = new TestMethodWriterHelper();
        
        assertNotNull(t);
    }
    
    @Test
    @InvocationCount(10)
    public void testOpenMethodDeclaration(
            @Pattern(regexp = "( |public|private|protected)") String access,
            @Pattern(regexp = "(void|int|float|double|String|Object)") String returnType,
            @Pattern(regexp = "[a-z][a-zA-Z0-9]*") String methodName)
            throws Exception {
        String expected = "@Test";

        TestMethodWriterHelper.openMethodDeclaration(writer, access,
                returnType, methodName, null);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "@InvocationCount(10)";
        assertEquals(expected, reader.readLine());

        expected = "\t" + access + " " + returnType + " " + methodName + "() {";
        assertEquals(expected, reader.readLine());

    }

    @Test
    @InvocationCount(10)
    public void testOpenPublicMethodDeclaration(
            @Pattern(regexp = "(void|int|float|double|String|Object)") String returnType,
            @Pattern(regexp = "[a-z][a-zA-Z0-9]*") String methodName)
            throws Exception {
        String expected = "@Test";

        TestMethodWriterHelper.openPublicMethodDeclaration(writer, returnType,
                methodName, null);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "@InvocationCount(10)";
        assertEquals(expected, reader.readLine());

        expected = "\tpublic " + returnType + " " + methodName + "() {";
        assertEquals(expected, reader.readLine());
    }

    @Test
    @InvocationCount(10)
    public void testOpenPrivateMethodDeclaration(
            @Pattern(regexp = "(void|int|float|double|String|Object)") String returnType,
            @Pattern(regexp = "[a-z][a-zA-Z0-9]*") String methodName)
            throws Exception {
        String expected = "@Test";

        TestMethodWriterHelper.openPrivateMethodDeclaration(writer, returnType,
                methodName, null);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "@InvocationCount(10)";
        assertEquals(expected, reader.readLine());

        expected = "\tprivate " + returnType + " " + methodName + "() {";
        assertEquals(expected, reader.readLine());
    }

    @Test
    @InvocationCount(10)
    public void testOpenProtectedMethodDeclaration(
            @Pattern(regexp = "(void|int|float|double|String|Object)") String returnType,
            @Pattern(regexp = "[a-z][a-zA-Z0-9]*") String methodName)
            throws Exception {
        String expected = "@Test";

        TestMethodWriterHelper.openProtectedMethodDeclaration(writer,
                returnType, methodName, null);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "@InvocationCount(10)";
        assertEquals(expected, reader.readLine());

        expected = "\tprotected " + returnType + " " + methodName + "() {";
        assertEquals(expected, reader.readLine());
    }

    @Test
    @InvocationCount(10)
    public void testOpenNothingMethodDeclaration(
            @Pattern(regexp = "(void|int|float|double|String|Object)") String returnType,
            @Pattern(regexp = "[a-z][a-zA-Z0-9]*") String methodName)
            throws Exception {
        String expected = "@Test";

        TestMethodWriterHelper.openNothingMethodDeclaration(writer,
                returnType, methodName, null);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "@InvocationCount(10)";
        assertEquals(expected, reader.readLine());

        expected = "\t" + returnType + " " + methodName + "() {";
        assertEquals(expected, reader.readLine());
    }

}
